﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace PDFWriter
{
    public class PDFCatalog : INode
    {
        public const string CATALOG_TAG = "Catalog";
        const string OBJECT_ID = "id";
        public const string GENERATION_ID = "GenID";
        public List<PDFObject> generatedObject = new List<PDFObject>();
        public string ReferenceID
        {
            get;
            set;
        }
        string xmlString = "<Catalog id=\"6\" metadata=\"\" info=\"\">" +
    "<Font id=\"4\">" +
      "<Dictionary>" +
        "<DictionaryElement type=\"name\" value=\"Type\">/Font</DictionaryElement>" +
        "<DictionaryElement type=\"name\" value=\"Subtype\">/Type1</DictionaryElement>" +
        "<DictionaryElement type=\"name\" value=\"Name\">/F1</DictionaryElement>" +
        "<DictionaryElement type=\"name\" value=\"BaseFont\">/Helvetica</DictionaryElement>" +
      "</Dictionary>" +
    "</Font>" +
    "<DocumentRoot id=\"5\" MediaBox=\"0,0,612,792\" >" +
      "<Page id=\"1\">" +
        "<Resource id=\"3\">          " +
          "<Dictionary>" +
             "<DictionaryElement type=\"name\" value=\"ProcSet\">" +
               "<Array>" +
                 "<ArrayElement>/PDF</ArrayElement>" +
                 "<ArrayElement>/Text</ArrayElement>" +
               "</Array>" +
             "</DictionaryElement>" +
             "<DictionaryElement type=\"name\" value=\"Font\">" +
               "<Dictionary>" +
                 "<DictionaryElement type=\"name\" value=\"F1\"><ObjRef>4</ObjRef></DictionaryElement>" +
               "</Dictionary>" +
             "</DictionaryElement>   " +
           "</Dictionary>" +
        "</Resource>" +
        "<Content id=\"2\">" +
            "<Dictionary>" +
              "<DictionaryElement type=\"name\" value=\"length\">51</DictionaryElement>" +
            "</Dictionary>" +
            "<Stream>" +
              "BT\n" +
              "/F1 24 Tf\n" +
              "1 0 0 1 260 600 Tm\n" +
              "(Hello World)Tj\n" +
              "ET\n" +
            "</Stream>           \n" +
          "</Content>        \n" +
      "</Page>      \n" +
    "</DocumentRoot>\n" +
  "</Catalog>";

        XmlDocument reader = new XmlDocument();

        public PDFCatalog(string xmlString)
        {
            this.xmlString = xmlString;
            reader.LoadXml(xmlString);
        }

        public PDFCatalog()
        {
            reader.LoadXml(xmlString);
        }

        private string ProcessXML()
        {


            string generationID = null;
            if (reader.FirstChild.Name == CATALOG_TAG)
            {
                if (reader.FirstChild.Attributes[OBJECT_ID].Value != null)
                {
                    generationID = reader.FirstChild.Attributes[OBJECT_ID].Value;
                    if (reader.FirstChild.Attributes[GENERATION_ID] != null)
                    {
                        generationID += reader.FirstChild.Attributes[GENERATION_ID].Value;
                    }
                    else
                    {
                        generationID += " 0";
                    }

                }
            }
            ReferenceID = generationID + " R";
            StringBuilder builder = new StringBuilder();
            foreach (XmlNode node in reader.FirstChild.ChildNodes)
            {
                generatedObject.AddRange(Utility.GetPDFObjects(node.OuterXml));
            }
            string rootID = GetDocumentRoot(generatedObject);

            if (reader.FirstChild.Name == CATALOG_TAG)
            {
                builder.Append("<<\n/Type /Catalog\n");
                builder.Append("/Pages " + rootID + "\n>>");
            }
            string fullText = generationID + " obj" + builder.ToString() + "\nendobj";
            generatedObject.Add(GenerateObject(fullText));
            return fullText;
        }

        private string GetDocumentRoot(List<PDFObject> pdfList)
        {
            string referenceID = null;
            foreach (PDFObject item in pdfList)
            {
                if (item.ObjectType == DocumentRoot.DOCUMENT_ROOT)
                {
                    referenceID = item.ObjectID;
                }
            }

            return referenceID;
        }

        private PDFObject GenerateObject(string fullText)
        {
            return new PDFObject() { Text = fullText, ObjectID = ReferenceID, ObjectType = CATALOG_TAG };
        }

        #region INode Members

        public PDFObject GetPDFObject()
        {
            return GenerateObject(ProcessXML());
        }

        public List<PDFObject> GetPDFObjects()
        {
            ProcessXML();
            return generatedObject;
        }

        #endregion
    }
}
